package kib.fun.server.gui;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.HashSet;
import java.util.Set;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenuBar;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;

import kib.fun.server.connection.ClientThread;
import kib.fun.server.connection.Server;

public class ServerStartPanel extends JPanel {
	
	private Server server = null;
	ClientThread echo;
	JMenuBar menu = new JMenuBar();
	JFrame frame = new JFrame();
	JPanel topPanel = new JPanel();
	JPanel midPanel = new JPanel();
	JPanel botPanel = new JPanel();
	JPanel clientPanel = new JPanel();
	
	
	JLabel ipLabel = new JLabel("");
	JLabel ipDescription = new JLabel("Server ip:");
	JLabel statusLabel = new JLabel("Status");
	JLabel status = new JLabel();
	
	
	JLabel portLabel = new JLabel("Port");
	JTextField portField = new JTextField(10);
	JButton startButton = new JButton("Start Server");
	JButton stopButton = new JButton("Stop Server");
	JButton refreshButton = new JButton("Refresh");
	Thread statusThread;
	int clientUpdateCounter = 0;
	boolean isStatusThreadRunning = true;
	public static void main(String[] args){
		ServerStartPanel ssp = new ServerStartPanel();
	}
	
	
	public ServerStartPanel(){
		init();
		frame.add(this);
		frame.pack();
		frame.setVisible(true);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}
	
	private void init(){
		this.server = new Server();
		
		this.setLayout(new BorderLayout());
		
		topPanel.setLayout(new FlowLayout());
		topPanel.add(ipDescription);
		topPanel.add(ipLabel);
		ipLabel.setText(IpErmittler.getIpAdresse());
		topPanel.add(statusLabel);
		topPanel.add(status);
		fillClientPanel();
		
		this.add(topPanel,BorderLayout.NORTH);
		
		this.add(midPanel,BorderLayout.CENTER);
		this.add(botPanel,BorderLayout.SOUTH);
		clientPanel.setPreferredSize(new Dimension(400,100));
		JScrollPane clientScrollPane = new JScrollPane();
		clientScrollPane.setViewportView(clientPanel);
		this.add(clientScrollPane,BorderLayout.EAST);
		frame.getRootPane().setDefaultButton(startButton);
		portField.setText(String.format("%s",server.getPort()));
		portField.setSelectionStart(0);
		portField.setSelectionEnd(portField.getText().length());
		midPanel.setLayout(new GridLayout(0, 4));
		
		midPanel.add(portLabel);
		midPanel.add(portField);
		statusThread = new Thread(){

			@Override
			public void run() {
				while(isStatusThreadRunning){
					status.setText(server.getStatus());
					try {
						Thread.sleep(100);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				};
			}
			
		};
		statusThread.start();
		
		botPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
		botPanel.add(startButton);
		startButton.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent arg0) {
				int port = server.getPort();
				try{
					port = Integer.parseInt(portField.getText());
					server.setPort(port);
					frame.getRootPane().setDefaultButton(stopButton);
				}catch(Exception ex){
					ex.printStackTrace();
				}
				
				server.startServer();
				
				
				System.out.println("Server started");
			}
		});
		botPanel.add(stopButton);
		stopButton.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				server.stopServer();
				System.out.println("Server stopped");
				frame.getRootPane().setDefaultButton(startButton);
			}
		});
		
		botPanel.add(refreshButton);
		refreshButton.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent arg0) {
				System.out.println("Refreshing Client list");
				fillClientPanel();
				
			}
		});
		
	}


	private void fillClientPanel() {
		clientUpdateCounter++;
		clientPanel.removeAll();
		clientPanel.setLayout(new GridLayout(0,1));
		final Set<ClientThread> clientThreads = new HashSet<ClientThread>();
		
		for(Object o:server.getClients()){
			if(o instanceof ClientThread){
				final ClientThread th = (ClientThread) o;
				clientThreads.add(th);
				System.out.println(String.format("Found ClientThread %s",th.toString()));
				final JLabel clientName = new JLabel(String.format("%s:%s", th.getIpAdress(),th.getPort()));
				final JTextField inputField = new JTextField(10);
				final JButton sendButton = new JButton("send");
				sendButton.addActionListener(new ActionListener() {
					
					@Override
					public void actionPerformed(ActionEvent arg0) {
						th.sendMessage(inputField.getText());
						
					}
				});
				final JPanel helpPanel = new JPanel();
				helpPanel.setPreferredSize(new Dimension(100,200));
				helpPanel.setLayout(new GridLayout(0, 1));
				final JScrollPane scrollPane = new JScrollPane();
				final JTextArea messageArea = new JTextArea();
				messageArea.setAutoscrolls(true);
				scrollPane.setViewportView(messageArea);
				final JPanel helpPanel2 = new JPanel();
				helpPanel2.setLayout(new FlowLayout());
				helpPanel2.add(clientName);
				helpPanel2.add(inputField);
				helpPanel2.add(sendButton);
				Thread messageUpdate = new Thread(){

					@Override
					public void run() {
						final int counter = clientUpdateCounter;
						while(clientUpdateCounter==counter){
							if(!messageArea.hasFocus()&&!scrollPane.hasFocus()){
								messageArea.setText(th.getMessages());
								messageArea.setCaretPosition(messageArea.getText().length());
								scrollPane.getVerticalScrollBar().setValue(scrollPane.getVerticalScrollBar().getMaximum());
								scrollPane.validate();
								messageArea.validate();
								if(!th.isAlive()&&clientUpdateCounter==counter){
									fillClientPanel();
								}
							}
							try {
								Thread.sleep(100);
							} catch (InterruptedException e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
							}
						}
						System.out.println("Terminated message update Thread");
					}
					
				};
				messageUpdate.start();
				helpPanel.add(scrollPane);
				helpPanel.add(helpPanel2);
				clientPanel.add(helpPanel);
				clientPanel.validate();
			}
		}
		
		Thread clientWatcher = new Thread(){

			@Override
			public void run() {
				final int counter = clientUpdateCounter;
				marker: while(clientUpdateCounter==counter){
					for(Object o:server.getClients()){
						if(o instanceof ClientThread){
							final ClientThread th = (ClientThread) o;
							if(!clientThreads.contains(th)){
								System.out.println("Breaking ClientUpdater");
								fillClientPanel();
								break marker;
							}
						}
					}
					try {
						Thread.sleep(100);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
			
			
			
		};
		clientWatcher.start();
	}

}
